/************************************************************************
                                                                     
   Xceed Ultimate ListBox for Silverlight                                                                                                                                            
   Copyright (C) 2010 Xceed Software Inc.    
                                                                     
   This program is provided to you under the terms of the GNU General Public  
   License version 2 as published by the Free Software Foundation. 
        
   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY, without even the implied warranty of 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License along 
   with this program, if not, write to the Free Software Foundation, Inc., 
   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

   This program can be provided to you by Xceed Software Inc. under a
   proprietary commercial license agreement for use in non-Open Source
   projects. Visit Xceed.com to find the commercial edition of 
   Xceed Ultimate ListBox for Silverlight.                                    
                                                                      
 **********************************************************************/

using System;
using System.ComponentModel;
using System.Windows;
using Xceed.Silverlight.ListBox.PositioningFunction;

namespace Xceed.Silverlight.ListBox
{
  public abstract class View : ContainerConfigurationsBase, ISupportInitialize
  {
    #region IsActiveView Property

    public static readonly DependencyProperty IsActiveViewProperty = DependencyProperty.Register(
      "IsActiveView",
      typeof( bool ),
      typeof( View ),
      new PropertyMetadata(
        false,
        new PropertyChangedCallback( View.OnIsActiveViewChanged ) ) );

    public bool IsActiveView
    {
      get
      {
        return ( bool )this.GetValue( View.IsActiveViewProperty );
      }
      set
      {
        this.SetValue( View.IsActiveViewProperty, value );
      }
    }

    private static void OnIsActiveViewChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e )
    {
      View view = sender as View;

      if( view == null )
        return;

      if( view.IsInitializing )
        return;

      view.RaiseIsActiveViewChanged();
    }

    private void RaiseIsActiveViewChanged()
    {
      if( this.IsActiveViewChanged != null )
        this.IsActiveViewChanged( this, EventArgs.Empty );
    }

    internal event EventHandler IsActiveViewChanged;

    #endregion

    internal virtual IScalingFunction GetScalingFunction()
    {
      return null;
    }

    internal virtual IOpacityFunction GetOpacityFunction()
    {
      return null;
    }

    internal virtual IZIndexFunction GetZIndexFunction()
    {
      return null;
    }

    #region PositioningFunction Internal Property

    internal PositioningFunctionBase PositioningFunction
    {
      get
      {
        return m_positioningFunction;
      }
      set
      {
        if( m_positioningFunction != value )
        {
          m_positioningFunction = value;

          if( !this.IsInitializing )
            RaisePositioningFunctionChanged();
        }
      }
    }

    internal event EventHandler PositioningFunctionChanged;

    internal void RaisePositioningFunctionChanged()
    {
      if( this.PositioningFunctionChanged != null )
        this.PositioningFunctionChanged( this, EventArgs.Empty );
    }

    #endregion

    #region BringLastItemToStartingPoint Internal Property

    internal virtual bool BringLastItemToStartingPoint
    {
      get
      {
        return false;
      }
    }

    #endregion

    #region ContainerSizeConstraint Internal Property

    internal ContainerLayoutMode PositioningContainerLayoutMode
    {
      get
      {
        return m_positioningContainerLayoutMode;
      }
      set
      {
        if( value != m_positioningContainerLayoutMode )
        {
          if( value == ContainerLayoutMode.Default )
            throw new InvalidOperationException( "An attempt was made to set the View's PositioningContainerLayoutMode to ContainerLayoutMode.Default." );

          m_positioningContainerLayoutMode = value;
        }
      }
    }

    #endregion

    #region AllowStickyHeaders Internal Read-Only Property

    internal virtual bool AllowStickyHeaders
    {
      get
      {
        return true;
      }
    }

    #endregion

    #region internal
    internal virtual double GetConfigurationDistanceUsedForExtent( ListBoxContainerConfigurationBase configuration )
    {
      return configuration.PrepareSize.Height;
    }
    #endregion

    #region Private Fields

    private PositioningFunctionBase m_positioningFunction;
    private ContainerLayoutMode m_positioningContainerLayoutMode = ContainerLayoutMode.Floating;

    #endregion

    #region ISupportInitialize Members

    void ISupportInitialize.BeginInit()
    {
      m_initializingCount++;
      this.BeginInitCore();
    }

    void ISupportInitialize.EndInit()
    {
      m_initializingCount--;

      if( m_initializingCount == 0 )
        this.EndInitCore();
    }

    internal bool IsInitializing
    {
      get
      {
        return ( m_initializingCount > 0 );
      }
    }

    internal virtual void BeginInitCore()
    {
    }

    internal virtual void EndInitCore()
    {
      if( this.IsActiveView )
        this.RaiseIsActiveViewChanged();
    }

    private int m_initializingCount;

    #endregion
  }
}
